#ifndef COURSE_H
#define COURSE_H

#include "TimeSlot.h"

class Course
{
public:
  Course(const std::string& _name)
      : name(_name), time_slots(new TimeSlots)
  { }

  Course(const std::string& _name, const TimeSlotsPtr& _time_slots)
    : name(_name), time_slots(_time_slots)
  { }

  const std::string&
  getCourseName() const
  {
    return name;
  }

  const TimeSlotsPtr&
  getTimeSlots() const
  {
    return time_slots;
  }

  void
  add_time_slot(const TimeSlotPtr& ts)
  {
    time_slots->push_back(ts);
  }

private:
  std::string name;
  TimeSlotsPtr time_slots;
};



typedef boost::shared_ptr<Course> CoursePtr;
typedef std::vector<CoursePtr> Courses;
typedef boost::shared_ptr<Courses> CoursesPtr;


std::ostream&
operator<< (std::ostream& os, const Course& c)
{
  os << c.getCourseName() << "[";
  
  TimeSlotsPtr ts = c.getTimeSlots();
  
  //std::copy(ts->begin(), ts->end(), std::ostream_iterator<PtimePtr> (os, " "));
  
  TimeSlots::const_iterator it = ts->begin();
  TimeSlots::const_iterator end = ts->end();
  --end;
  
  for (; it != end; ++it)      
    {
      os << *it << ", ";
    }
  
  os << *it << "]";
  
  return os;
}


std::ostream&
operator<< (std::ostream& os, const CoursePtr& c)
{
  os << *c;
  return os;
}


std::ostream&
operator<< (std::ostream& os, const CoursesPtr& cs)
{
  std::copy(cs->begin(), cs->end(), std::ostream_iterator<CoursePtr> (os, "\n"));
  return os;
}


class CompareCourses
{
public:
  CompareCourses(const std::string& _course_name)
    : course_name(_course_name)
  { }

  bool
  operator() (const CoursePtr& c)
  {
    return (c->getCourseName() == course_name);
  }

private:
  std::string course_name; 
};


class OverlappingCourses
{
public:
  OverlappingCourses(const CoursePtr& _courses)
    : my_courses(_courses)
  { }

  bool
  operator() (const CoursePtr& c)
  {
    TimeSlotsPtr ts1 = my_courses->getTimeSlots();
    TimeSlotsPtr ts2 = c->getTimeSlots();

    TimeSlots::const_iterator it = std::find_first_of(ts1->begin(), ts1->end(), ts2->begin(), ts2->end(), CompareTimeSlots());

    return (it != ts1->end());
  }

private:
  CoursePtr my_courses;
};

#endif

// Local Variables:
// mode: C++
// End:
